package pro1.util;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class DateTime {
    private static Logger logger = LogManager.getLogger();

    // 获取当前日期，格式为：年-月-日(空格)时:分:秒

    public static String now() {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
    }
    // 根据日期获取年份

    public static int getYear(String date) {
        date = date.substring(0, date.indexOf("-"));
        return Integer.valueOf(date);
    }
    // 根据日期获取月

    public static int getMonth(String date) {
        date = date.substring(date.indexOf("-") + 1);
        date = date.substring(0, date.indexOf("-"));
        if (date.charAt(0) == '0') {
            date = date.substring(1);
        }
        return Integer.valueOf(date);
    }
    // 根据日期获取日

    public static int getDay(String date) {
        date = date.substring(date.indexOf("-") + 1);
        date = date.substring(date.indexOf("-") + 1, date.indexOf(" "));
        if (date.charAt(0) == '0') {
            date = date.substring(1);
        }
        return Integer.valueOf(date);
    }
    // 根据日期获取时间

    public static String getTime(String date) {
        return date.substring(date.indexOf(" ") + 1);
    }

    // 根据日期获取小时
    public static int getHours(String date) {
        date = getTime(date).substring(0, 2);
        if (date.charAt(0) == '0') {
            date = date.substring(1);
        }
        return Integer.valueOf(date);
    }

    // 根据日期获取分钟
    public static int getMinute(String date) {
        date = getTime(date).substring(3, 5);
        if (date.charAt(0) == '0') {
            date = date.substring(1);
        }
        return Integer.valueOf(date);
    }

    // 根据日期获取秒
    public static int getSecond(String date) {
        date = getTime(date).substring(6);
        if (date.charAt(0) == '0') {
            date = date.substring(1);
        }
        return Integer.valueOf(date);
    }

    // 根据日期获取年月日
    public static String ymd(String date) {
        return getYear(date) + "-" + (getMonth(date) < 10 ? ("0" + getMonth(date)) : getMonth(date)) + "-"
                + (getDay(date) < 10 ? ("0" + getDay(date)) : getDay(date));
    }

    // 时间戳格式
    public static String toTimeStamp(String date) {
        date = date.replaceAll("-", "");
        date = date.replaceAll(" ", "");
        date = date.replaceAll(":", "");
        return date;
    }

    // 求该日期与当前日期相隔年数
    public static int differentYears(String date) {
        int years = -1;
        String now = now();
        years = getYear(now) - getYear(date) - 1;
        if (getMonth(now) - getMonth(date) >= 0 && getDay(now) - getDay(date) >= 0) {
            years += 1;
        }
        return years;
    }
    // 求该日期与当前日期相隔天数

    public static int differentDays(String date) {
        int days = -1;
        String now = now();
        int d1 = theDays(now);
        int d2 = theDays(date);
        if (getYear(now) == getYear(date)) {
            days = Math.abs(d1 - d2);
        } else {
            if (getYear(now) - getYear(date) > 0) {
                for (int i = 0; i < getYear(now) - getYear(date) - 1; ++i) {
                    if (isLeapYear(getYear(date) + 1 + i)) {
                        days += 366;
                    } else {
                        days += 365;
                    }
                }
                if (isLeapYear(getYear(date))) {
                    days += 366 - d2;
                } else {
                    days += 365 - d2;
                }
                days += d1;
            } else {
                for (int i = 0; i < getYear(date) - getYear(now) - 1; ++i) {
                    if (isLeapYear(getYear(now) + 1 + i)) {
                        days += 366;
                    } else {
                        days += 365;
                    }
                }
                if (isLeapYear(getYear(now))) {
                    days += 366 - d2;
                } else {
                    days += 365 - d2;
                }
                days += d2;
            }
        }
        return days;
    }

    /**
     * 一分钟之后的时间
     *
     * @param oldDate
     * @return
     */
    public static String newDateMinuteLater(String oldDate, int addMinute) {
        StringBuffer newDate = new StringBuffer();
        int year = getYear(oldDate);
        int month = getMonth(oldDate);
        int day = getDay(oldDate);
        int hours = getHours(oldDate);
        int minute = getMinute(oldDate);
        int second = getSecond(oldDate);
        minute += addMinute;
        newDate.append(year);
        newDate.append('-');
        if (month < 10) {
            newDate.append(0);
        }
        newDate.append(month);
        newDate.append('-');
        if (day < 10) {
            newDate.append(0);
        }
        newDate.append(day);
        newDate.append(" ");
        if (hours < 10) {
            newDate.append(0);
        }
        newDate.append(hours);
        newDate.append(":");
        if (minute < 10) {
            newDate.append(0);
        }
        newDate.append(minute);
        newDate.append(":");
        if (second < 10) {
            newDate.append(0);
        }
        newDate.append(second);
        return newDate.toString();
    }


    /**
     * months月之后的时间
     *
     * @param oldDate
     * @param months
     * @return
     */
    public static String newDateMonthsLater(String oldDate, int months) {
        StringBuffer newDate = new StringBuffer();
        int year = getYear(oldDate);
        int month = getMonth(oldDate);
        int day = getDay(oldDate);
        month += months;
        while (true) {
            if (month > 12) {
                year += 1;
                month -= 12;
            } else {
                break;
            }
        }
        if (day == 31) {
            switch (month) {
                case 4:
                    day = 30;
                    break;
                case 6:
                    day = 30;
                    break;
                case 9:
                    day = 30;
                    break;
                case 11:
                    day = 30;
                    break;
                case 2:
                    if (isLeapYear(year)) {
                        day = 29;
                    } else {
                        day = 28;
                    }
                    break;
            }
        } else if (day > 29) {
            if (month == 2) {
                if (isLeapYear(year)) {
                    day = 29;
                } else {
                    day = 28;
                }
            }
        } else if (day == 29) {
            if (month == 2) {
                if (!isLeapYear(year)) {
                    day = 28;
                }
            }
        }
        newDate.append(year);
        newDate.append('-');
        if (month < 10) {
            newDate.append(0);
        }
        newDate.append(month);
        newDate.append('-');
        if (day < 10) {
            newDate.append(0);
        }
        newDate.append(day);
        newDate.append(oldDate.substring(10));
        return newDate.toString();
    }

    /**
     * 求days天后的时间（days不超过28）
     *
     * @param oldDate
     * @param days
     * @return
     */
    public static String newDateDaysLater(String oldDate, int days) {
        StringBuffer newDate = new StringBuffer();
        int year = getYear(oldDate);
        int month = getMonth(oldDate);
        int day = getDay(oldDate);
        day += days;
        while (true) {
            if (day > 31) {
                switch (month) {
                    case 4:
                        day -= 30;
                        break;
                    case 6:
                        day -= 30;
                        break;
                    case 9:
                        day -= 30;
                        break;
                    case 11:
                        day -= 30;
                        break;
                    case 2:
                        if (isLeapYear(year)) {
                            day -= 29;
                        } else {
                            day -= 28;
                        }
                        break;
                    default:
                        day -= 31;
                        break;
                }
                month += 1;
                if (month > 12) {
                    month = 1;
                    year += 1;
                }
            } else if (day == 31) {
                switch (month) {
                    case 4:
                        day -= 30;
                        month += 1;
                        if (month > 12) {
                            month = 1;
                            year += 1;
                        }
                        break;
                    case 6:
                        day -= 30;
                        month += 1;
                        if (month > 12) {
                            month = 1;
                            year += 1;
                        }
                        break;
                    case 9:
                        day -= 30;
                        month += 1;
                        if (month > 12) {
                            month = 1;
                            year += 1;
                        }
                        break;
                    case 11:
                        day -= 30;
                        month += 1;
                        if (month > 12) {
                            month = 1;
                            year += 1;
                        }
                        break;
                    case 2:
                        if (isLeapYear(year)) {
                            day -= 29;
                        } else {
                            day -= 28;
                        }
                        month += 1;
                        if (month > 12) {
                            month = 1;
                            year += 1;
                        }
                        break;
                }
            } else if (day > 29) {
                if (month == 2) {
                    if (isLeapYear(year)) {
                        day -= 29;
                        month += 1;
                        if (month > 12) {
                            month = 1;
                            year += 1;
                        }
                    } else {
                        day -= 28;
                        month += 1;
                        if (month > 12) {
                            month = 1;
                            year += 1;
                        }
                    }
                }
            } else if (day == 29) {
                if (month == 2) {
                    if (!isLeapYear(year)) {
                        day -= 28;
                        month += 1;
                        if (month > 12) {
                            month = 1;
                            year += 1;
                        }
                    }
                }
            }
            if (((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)
                    && day <= 31) || ((month == 4 || month == 6 || month == 9 || month == 11) && day <= 30)
                    || (isLeapYear(year) && month == 2 && day <= 29)
                    || (!isLeapYear(year) && month == 2 && day <= 28)) {
                break;
            }
        }
        newDate.append(year);
        newDate.append('-');
        if (month < 10) {
            newDate.append(0);
        }
        newDate.append(month);
        newDate.append('-');
        if (day < 10) {
            newDate.append(0);
        }
        newDate.append(day);
        newDate.append(oldDate.substring(10));
        return newDate.toString();
    }

    /**
     * 5分钟前的时间
     *
     * @param oldDate
     * @return
     */
    public static String newDate5MinuteAgo(String oldDate) {
        StringBuffer newDate = new StringBuffer();
        int year = getYear(oldDate);
        int month = getMonth(oldDate);
        int day = getDay(oldDate);
        int hours = getHours(oldDate);
        int minute = getMinute(oldDate);
        int second = getSecond(oldDate);
        if (minute < 5) {
            if (hours == 0) {
                if (day == 1) {
                    if (month == 1) {
                        year -= 1;
                        month = 12;
                        day = 31;
                        hours = 23;
                        minute += 60;
                        minute -= 5;
                    } else {
                        switch (month) {
                            case 4:
                                day = 30;
                                break;
                            case 6:
                                day = 30;
                                break;
                            case 9:
                                day = 30;
                                break;
                            case 11:
                                day = 30;
                                break;
                            case 2:
                                if (isLeapYear(year)) {
                                    day = 29;
                                } else {
                                    day = 28;
                                }
                                break;
                            default:
                                day = 31;
                                break;
                        }
                        month -= 1;
                        hours = 23;
                        minute += 60;
                        minute -= 5;
                    }
                } else {
                    day -= 1;
                    hours = 23;
                    minute += 60;
                    minute -= 5;
                }
            } else {
                hours -= 1;
                minute += 60;
                minute -= 5;
            }
        } else {
            minute -= 5;
        }
        newDate.append(year);
        newDate.append('-');
        if (month < 10) {
            newDate.append(0);
        }
        newDate.append(month);
        newDate.append('-');
        if (day < 10) {
            newDate.append(0);
        }
        newDate.append(day);
        newDate.append(" ");
        newDate.append(hours);
        newDate.append(":");
        newDate.append(minute);
        newDate.append(":");
        newDate.append(second);
        return newDate.toString();
    }

    /*
     * days天前的时间
     */
    public static String newDateDaysAgo(String oldDate, int days) {
        StringBuffer newDate = new StringBuffer();
        int year = getYear(oldDate);
        int month = getMonth(oldDate);
        int day = getDay(oldDate);
        if (day > days) {
            day -= days;
        } else {
            while (!(((month - 1 == 1 || month - 1 == 3 || month - 1 == 5 || month - 1 == 7 || month - 1 == 8
                    || month - 1 == 10 || month == 1) && day + 31 > days)
                    || ((month - 1 == 4 || month - 1 == 6 || month - 1 == 9 || month - 1 == 11) && day + 30 > days)
                    || (isLeapYear(year) && month - 1 == 2 && day + 29 > days)
                    || (!isLeapYear(year) && month - 1 == 2 && day + 28 > days))) {
                if (month != 1) {
                    switch (month - 1) {
                        case 4:
                            days -= 30;
                            break;
                        case 6:
                            days -= 30;
                            break;
                        case 9:
                            days -= 30;
                            break;
                        case 11:
                            days -= 30;
                            break;
                        case 2:
                            if (isLeapYear(year)) {
                                days -= 29;
                            } else {
                                days -= 28;
                            }
                            break;
                        default:
                            days -= 31;
                            break;
                    }
                    month -= 1;
                } else {
                    year -= 1;
                    month = 12;
                }
            }
            if (month != 1) {
                switch (month - 1) {
                    case 4:
                        day += 30;
                        break;
                    case 6:
                        day += 30;
                        break;
                    case 9:
                        day += 30;
                        break;
                    case 11:
                        day += 30;
                        break;
                    case 2:
                        if (isLeapYear(year)) {
                            day += 29;
                        } else {
                            day += 28;
                        }
                        break;
                    default:
                        day += 31;
                        break;
                }
                month -= 1;
                day -= days;
            } else {
                year -= 1;
                month = 12;
                day = day + 31 - days;
            }
        }
        newDate.append(year);
        newDate.append('-');
        if (month < 10) {
            newDate.append(0);
        }
        newDate.append(month);
        newDate.append('-');
        if (day < 10) {
            newDate.append(0);
        }
        newDate.append(day);
        newDate.append(oldDate.substring(10));
        return newDate.toString();
    }

    /**
     * 比较date1是否大于date2
     *
     * @param date1
     * @param date2
     * @return
     */
    public static boolean comparison(String date1, String date2) {
        boolean f = false;
        if (getYear(date1) > getYear(date2)) {
            f = true;
        } else if (getYear(date1) == getYear(date2)) {
            if (getMonth(date1) > getMonth(date2)) {
                f = true;
            } else if (getMonth(date1) == getMonth(date2)) {
                if (getDay(date1) > getDay(date2)) {
                    f = true;
                } else if (getDay(date1) == getDay(date2)) {
                    if (getHours(date1) > getHours(date2)) {
                        f = true;
                    } else if (getHours(date1) == getHours(date2)) {
                        if (getMinute(date1) >= getMinute(date2)) {
                            f = true;
                        }
                    }
                }
            }
        }
        return f;
    }
    // 判断是不是闰年

    public static boolean isLeapYear(int year) {
        boolean f = false;
        if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
            f = true;
        }
        return f;
    }
    // 计算该日期是该年的第几天

    public static int theDays(String date) {
        int days = 0;
        for (int i = 1; i <= getMonth(date) - 1; ++i) {
            switch (i) {
                case 4:
                    days += 30;
                    break;
                case 6:
                    days += 30;
                    break;
                case 9:
                    days += 30;
                    break;
                case 11:
                    days += 30;
                    break;
                case 2:
                    if (isLeapYear(getYear(date))) {
                        days += 29;
                    } else {
                        days += 28;
                    }
                    break;
                default:
                    days += 31;
                    break;
            }
        }
        days += getDay(date);
        return days;
    }
    // 获取标准时间

    public static String TransferTime(String date) {
        return date.substring(0, date.lastIndexOf("."));
    }

    public static String toType(String date) {
        date = date.substring(0, 19);
        date = date.replace('T', ' ');
        return date;
    }

    // 获取5年内时间
    public static String[] getBetwen5Years(String ymd) {
        String[] s = new String[2];
        String date = ymd + " 00:00:00";
        StringBuffer sb1 = new StringBuffer();
        sb1.append(getYear(date) - 5);
        sb1.append("-");
        sb1.append(getMonth(date));
        sb1.append("-");
        sb1.append(getDay(date));
        StringBuffer sb2 = new StringBuffer();
        sb2.append(getYear(date) + 5);
        sb2.append("-");
        sb2.append(getMonth(date));
        sb2.append("-");
        sb2.append(getDay(date));
        s[0] = sb1.toString();
        s[1] = sb2.toString();
        return s;
    }

    // 转化成Date格式
    public static Date toDate(String dateTime) {
        SimpleDateFormat adf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        try {
            date = adf.parse(dateTime);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return date;
    }

    /**
     * * 获取指定日期是星期几
     * <p>
     * 参数为null时表示获取当前日期是星期几
     *
     * @param date
     * @return
     */

    public static String getWeekOfDate(Date date) {

        String[] weekOfDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};

        Calendar calendar = Calendar.getInstance();

        if (date != null) {

            calendar.setTime(date);

        }

        int w = calendar.get(Calendar.DAY_OF_WEEK) - 1;

        if (w < 0) {

            w = 0;

        }

        return weekOfDays[w];

    }

    /**
     * date2比date1多的天数
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int differentDays(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        int day1 = cal1.get(Calendar.DAY_OF_YEAR);
        int day2 = cal2.get(Calendar.DAY_OF_YEAR);

        int year1 = cal1.get(Calendar.YEAR);
        int year2 = cal2.get(Calendar.YEAR);
        if (year1 != year2) // 同一年
        {
            int timeDistance = 0;
            for (int i = year1; i < year2; i++) {
                if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) // 闰年
                {
                    timeDistance += 366;
                } else // 不是闰年
                {
                    timeDistance += 365;
                }
            }

            return timeDistance + (day2 - day1);
        } else // 不同年
        {
            logger.info("判断day2 - day1 : " + (day2 - day1));
            return day2 - day1;
        }
    }

    public static String getFutureDays(Integer days) {
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_MONTH, days);
        Date time = c.getTime();
        String format = sf.format(time);
        return format;
    }

    public static void main(String[] args) {
        //System.out.println(getFutureDays(60));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String s = newDateMonthsLater(sdf.format(new Date()), 2);
        System.out.println(s);
    }

    /**
     * 获取当前时间 x个月后的时间
     *
     * @param month
     * @return
     */
    public static String getFurtureMonth(Integer month) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, month);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        logger.info(month + "个月以后的时间：" + sdf.format(calendar.getTime()));
        return sdf.format(calendar.getTime());
    }

    /**
     * 获取当前时间x年后的时间
     *
     * @param year
     * @return
     */
    public static String getFurtureYear(Integer year) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR, year);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        logger.info(year+"年以后的时间：" + sdf.format(calendar.getTime()));
        return sdf.format(calendar.getTime());
    }

    public static Long getDatePoor(Date endDate, Date nowDate) {

        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;
        // 计算差多少秒//输出结果
        // long sec = diff % nd % nh % nm / ns;
        return hour;
    }
}
